/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Web.Services.Protocols;
using System.Xml;

using Anculus.Core;

namespace Galaxium.Protocol.Msn.Soap
{
	internal class LogExtension : SoapExtension
	{
		Stream oldStream;
        Stream newStream;
		
		public override void Initialize (object initializer)
		{
			
		}

		public override object GetInitializer (LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
		{
			return null;
		}
		
		public override object GetInitializer (Type serviceType)
		{
			return null;
		}
		
		public override Stream ChainStream (Stream stream)
        {
			oldStream = stream;
            newStream = new MemoryStream ();
            return newStream;
        }
		
		public override void ProcessMessage (SoapMessage message)
		{
			switch (message.Stage) 
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    WriteOutput (message);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    WriteInput (message);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
                default:
                    throw new Exception("invalid stage");
            }
		}
		
		public void WriteOutput (SoapMessage message)
        {
			newStream.Position = 0;
			
			StreamReader reader = new StreamReader (newStream);
			Console.WriteLine (FormatXML (reader.ReadToEnd ()));
			
            newStream.Position = 0;
            Copy(newStream, oldStream);
        }

        public void WriteInput (SoapMessage message)
        {
            Copy (oldStream, newStream);

            newStream.Position = 0;
			
			StreamReader reader = new StreamReader (newStream);
			Console.WriteLine (FormatXML (reader.ReadToEnd ()));
			
            newStream.Position = 0;
        }

        void Copy (Stream from, Stream to) 
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }
		
		public static string FormatXML (string xml)
		{ 
			try
			{
				XmlDocument doc = new XmlDocument ();
				doc.LoadXml (xml);
				
				using (StringWriter sw = new StringWriter ())
				{
					XmlTextWriter xtw = new XmlTextWriter (sw);
					xtw.Formatting = System.Xml.Formatting.Indented;
					doc.WriteTo (xtw);
					
					return sw.ToString ();
				}
			}
			catch
			{
				Log.Debug ("Unable to format XML");
				return xml;
			}
		}
	}
	
	public class LogExtensionAttribute : SoapExtensionAttribute
	{
		int _priority;
		
		public override Type ExtensionType
		{
			get { return typeof (LogExtension); }
		}

		public override int Priority
		{
			get { return _priority; }
			set { _priority = value; }
		}
	}
}
